import 'dart:async';
import 'dart:convert';

import 'package:flutter_app/bean/respon.dart';
import 'package:http/http.dart' as http;
import 'package:rxdart/rxdart.dart';
import 'package:shared_preferences/shared_preferences.dart';

List<StreamSubscription> _obs = new List();

void clearOb() async {
  for (var value in _obs) {
    await value.cancel();
  }
}

//1.1 首页文章列表
void getDataList(void onData(Object data), int page) {
  var dataUrl = "http://www.wanandroid.com/article/list/$page/json";
  var listen = new Observable.just(dataUrl)
      .flatMap((url) => new Observable.fromFuture(http.get(url)))
      .map((response) => response.body)
      .map((jsonBody) => json.decode(jsonBody))
      .map(_checkResultAndGetData)
      .map((jsonMap) => new OnePageData.fromJson(jsonMap).datas)
      .listen(onData);
  _obs.add(listen);
}

//1.2 首页banner
void getBannerList(void onData(dynamic data)) {
  var bannerUrl = "http://www.wanandroid.com/banner/json";
  var listen = new Observable.just(bannerUrl)
      .flatMap((url) => new Observable.fromFuture(http.get(url)))
      .map((response) => json.decode(response.body))
      .map(_checkResultAndGetData)
      .flatMap((jsonMap) => new Observable.fromIterable(jsonMap))
      .interval(new Duration(seconds: 3))
      .map((jsonMap) => jsonMap['imagePath'])
      .listen(onData);
  _obs.add(listen);
}

//5.1 登录
void login(void onData(dynamic data), String username, String password) {
  var loginUrl = "http://www.wanandroid.com/user/login";
  var listen = new Observable.just(loginUrl)
      .flatMap((url) => new Observable.fromFuture(
          http.post(url, body: {"username": username, "password": password})))
      .doOnData((data) {
        new Observable.fromFuture(SharedPreferences.getInstance())
            .map((sp) => sp.setString('Cookie', data.headers['set-cookie']))
            .flatMap((ret) => new Observable.fromFuture(ret))
            .map((convert) => convert ? "保存成功" : "保存失败")
            .listen(print);
      })
      .map((response) => response.body)
      .map((jsonData) => json.decode(jsonData))
      .map(_checkResultAndGetData)
      .listen(onData);
  _obs.add(listen);
}

//4.1 项目分类
void getClassification(void onData(dynamic data)) {
  var url = "http://www.wanandroid.com/project/tree/json";
  var listen = new Observable.just(url)
      .flatMap((url) => new Observable.fromFuture(http.get(url)))
      .map((response) => response.body)
      .map((jsonData) => json.decode(jsonData))
      .map(_checkResultAndGetData)
      .listen(onData);
  _obs.add(listen);
}

//4.2 项目列表数据
void getCategoryInfoList(void onData(dynamic data), int page, int cid) {
  var url = "http://www.wanandroid.com/project/list/$page/json?cid=$cid";
  var listen = new Observable.just(url)
      .flatMap((url) => new Observable.fromFuture(http.get(url)))
      .map((response) => response.body)
      .map((jsonData) => json.decode(jsonData))
      .map(_checkResultAndGetData)
      .map((jsonMap) => jsonMap['datas'])
      .listen(onData);
  _obs.add(listen);
}

//6.1 收藏文章列表
void getCollectionList(void onData(data), int page) {
  var url = "http://www.wanandroid.com/lg/collect/list/$page/json";
  var listen = Observable
      .zip2(
          new Observable.just(url),
          new Observable.fromFuture(SharedPreferences.getInstance()).map((sp) =>
              sp.getString("Cookie") == null ? "" : sp.getString("Cookie")),
          _getCollectionWithCookie)
      .flatMap((ob) => ob)
      .map((response) => response.body)
      .map((jsonData) => json.decode(jsonData))
      .map(_checkResultAndGetData)
      .map((jsonMap) => jsonMap['datas'])
      .listen(onData, onError: print);
  _obs.add(listen);
}

/*请求头带有cookie,请求服务器数据*/
Observable<http.Response> _getCollectionWithCookie(String url, String cookie) {
  if (cookie == "") {
    throw new Exception("没有找到保存的cookie");
  }
  return new Observable.fromFuture(http.get(
    url,
    headers: {
      "Cookie": cookie,
    },
  ));
}

//6.2 收藏站内文章
void collectionInfo(void onData(data), int originId) {
  var url = "http://www.wanandroid.com/lg/collect/$originId/json";
  var listen = Observable
      .zip2(
          new Observable.just(url),
          new Observable.fromFuture(SharedPreferences.getInstance()).map((sp) =>
              sp.getString("Cookie") == null ? "" : sp.getString("Cookie")),
          _unCollectionWithCookie)
      .flatMap((ob) => ob)
      .map((response) => response.body)
      .map((jsonData) => json.decode(jsonData))
      .listen(onData, onError: print);
  _obs.add(listen);
}

//6.4 取消收藏
void unCollection(void onData(data), int originId) {
  var url = "http://www.wanandroid.com/lg/uncollect_originId/$originId/json";
  var listen = Observable
      .zip2(
          new Observable.just(url),
          new Observable.fromFuture(SharedPreferences.getInstance()).map((sp) =>
              sp.getString("Cookie") == null ? "" : sp.getString("Cookie")),
          _unCollectionWithCookie)
      .flatMap((ob) => ob)
      .map((response) => response.body)
      .map((jsonData) => json.decode(jsonData))
      .map(_checkResultAndGetData)
      .listen(onData, onError: print);
  _obs.add(listen);
}

/*请求头带有cookie,请求服务器数据*/
Observable<http.Response> _unCollectionWithCookie(String url, String cookie) {
  if (cookie == "") {
    throw new Exception("没有找到保存的cookie");
  }
  return new Observable.fromFuture(http.post(
    url,
    headers: {
      "Cookie": cookie,
    },
  ));
}

/*验证服务器返回数据如果不符合约定要求,抛出异常*/
dynamic _checkResultAndGetData(jsonData) {
  if (jsonData['errorCode'] != 0) {
    throw new _DataLoadException(jsonData['errorMsg']);
  } else {
    return jsonData['data'] == null ? jsonData : jsonData['data'];
  }
}

/*自定义的服务数据异常,如果返回的errorCode不等于0则抛出该异常*/
class _DataLoadException implements Exception {
  final message;

  _DataLoadException([this.message]);

  String toString() {
    if (message == null) return "DataLoadException";
    return "DataLoadException: $message";
  }
}
